/**
 *  Copyright (C) 2012 by Development Solutions, Software (DSS)
 *  Released under the terms of the GNU General Public license version 3 or later
 */

package org.dss.gil.controller;

import java.awt.Component;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.Level;
import javax.help.HelpBroker;
import javax.help.HelpSet;
import javax.swing.ImageIcon;
import org.apache.log4j.Logger;
import org.xml.sax.SAXException;
import org.dss.gil.view.About;
import org.dss.gil.view.GlobalComments;
import org.dss.gil.view.Configurations;
import org.dss.gil.view.Ide;
import org.dss.gil.view.TablePanel;
import org.dss.gil.view.TextPanel;
import org.dss.gil.util.FileManager;
import org.dss.gil.util.FilesHandler;
import org.dss.gil.util.GiGenericException;
import org.dss.gil.util.Globals;
import org.dss.gil.service.MessagesService;
import org.dss.gil.interfaces.GenericFileInterface;
import org.dss.gil.service.GpssService;
import org.dss.gil.util.CmdConnector;
import org.dss.gil.util.SimTableModel;
import org.dss.gil.util.XMLBlocks;
import org.dss.gil.view.Calculator;
import org.dss.gil.view.Frequencies;

/** 
 *  @author  Fernando Gil <lobho.gil@gmail.com>
 *  @since   September 2012
 *  @version 1.0
 */

public class IdeMethods {

   /*********************************************************************
    **************** V A R I A B L E S  &  O B J E C T S ****************
    *********************************************************************/
    private static Logger logger = Logger.getLogger(IdeMethods.class.getName());
    private Ide ideView;
    private TextPanel  textPanel;
    private TablePanel tablePanel;
    
    private FilesHandler savedFiles;
    private FileManager file_manager;
    private MessagesService messages;
    private GpssService gpssService;
    private GenericFileInterface sav_int;
    private XMLBlocks xml_blocks;
    private boolean afloat;
    
    private final boolean OPEN_MULTISELECTION = true;
    public static Object [][] saved_rows;       // TablePanel's Clipboard 
    private String lineStatus;
    private String blockStatus;
    private int filesCounter = 0;
    
   /*********************************************************************
    ************************* S I N G L E T O N *************************
    *********************************************************************/
    private static IdeMethods INSTANCE = null;

    public static IdeMethods getInstance(Ide ide) {
        if (INSTANCE == null)
            INSTANCE = new IdeMethods(ide);
        return INSTANCE;
    }
    
    public static IdeMethods getCreatedInstance() {
        return INSTANCE;
    }

    private IdeMethods(Ide ide) {
        ideView = ide;
        loadDefaultValues();
        loadServices();
    }
    
   /*********************************************************************
    *************************** M E T H O D S ***************************
    *********************************************************************/
    
    private void loadDefaultValues(){
        afloat = false;
        lineStatus = Globals.language.getMessage("button.line");
        blockStatus = Globals.language.getMessage("button.block");
    }
    
    private void loadServices(){
        messages = MessagesService.getInstance();
        savedFiles = FilesHandler.getInstance();
        gpssService = GpssService.getInstance();
    }
    
    public void loadHelpWindow(){
        java.awt.EventQueue.invokeLater(new Runnable(){
            @Override
            public void run() {
                try {
                    URL helpUrl = new File(Globals.HELPSET_PATH).toURI().toURL();
                    HelpSet helpset = new HelpSet(getClass().getClassLoader(), helpUrl);
                    HelpBroker hb = helpset.createHelpBroker();
                    hb.initPresentation();
                    hb.setDisplayed(true);
                } catch (Exception ex) {
                    logger.error(ex.getMessage());
                }
            }
        });
    }

    public void loadAboutWindow(){
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                Globals.aboutView = About.getInstance();
                Globals.aboutView.setVisible(true);
            }
        });
    }
    
    public void loadConfigurationsWindow(){
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                Globals.confView = Configurations.getInstance();
                Globals.confView.setVisible(true);
            }
        });
    }
    
    public void loadCalc(){
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                Globals.calcView = Calculator.getInstance();
                Globals.calcView.setVisible(true);
            }
        });
    }
    
    public void loadFrequencies(){
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                Globals.frequenciesView = Frequencies.getInstance();
                Globals.frequenciesView.setVisible(true);
            }
        });
    }
            
    public void keepAfloat() {
        afloat = !afloat;
        String message = (afloat)?Globals.language.getMessage("message.afloat.on"):
                                  Globals.language.getMessage("message.afloat.off");
        messages.showInformationMessage(ideView,message,null);
        ideView.setAlwaysOnTop(afloat);
    }
    
    private boolean closinFrame = false;
    public void exit(){
        try {
            closinFrame = true;
            closeAll();
            System.exit(0);
        } catch (Exception ex) {
            logger.error(ex.getMessage());
        }
    }
    
    public void createNewSimulationFile(){
        tablePanel = new TablePanel();
        createNew(tablePanel, Globals.SIMFILE_NAME+ (++filesCounter), Globals.simfileIcon);
    }

    public void createNewTextFile(){
        textPanel = new TextPanel();
        createNew(textPanel, Globals.TEXTFILE_NAME+ (++filesCounter), Globals.textfileIcon);
    }
    
    public void openAsNewTextFile(String name, String content){
        textPanel = new TextPanel();
        textPanel.setText(content);
        createNew(textPanel, name, Globals.textfileIcon);
        textPanel.setSaved(false);
    }
    
    private void createNew(Component com, String fileName, ImageIcon icon) {
        if( isAvailableSpaceInTabs() ){
            GenericFileInterface file = (GenericFileInterface) com;
            file.setFileName( fileName ); 
            file.setSaved(true);
            file.setNew(true);
            ideView.getTabPane().addTab(file.getFileName(), icon, com, file.getFileName());
            ideView.getTabPane().setSelectedComponent(com);
        }
    }
    
    private boolean isAvailableSpaceInTabs(){
        if(ideView.getTabPane().getTabCount() > Globals.maxTabs){
            messages.showWarningMessage(this.ideView,Globals.language.getMessage("message.tabs.max"), null);
            return false;
        }else{
            return true;
        }
    }
    
    private boolean isSimulationFile(String name){
        return(name.endsWith(Globals.GIL_EXT) || name.endsWith(Globals.GIL_EXT+Globals.COPY_EXT));
    }
    
    public void openFileOrSelectIfExist(){
        if( isAvailableSpaceInTabs() ){
            File[] files = messages.openFileChooser(ideView);
            if(files!=null){
                for(File file : files){
                    try{
                        if(savedFiles.contains(file.getAbsolutePath())){
                            ideView.getTabPane().setSelectedComponent( savedFiles.getComponent(file.getAbsolutePath()));
                        }else if (isAvailableSpaceInTabs()){
                            if(isSimulationFile(file.getName())){
                                openAsSimulation(file);
                            }else{
                                openAsTextFile(file);
                            }
                        }
                    }catch(Exception ex){
                        logger.error(ex.getMessage());
                    }
                }
            }
        }
    }
    
    private void openAsSimulation(File file) throws SAXException, FileNotFoundException, IOException{
        String path = file.getAbsolutePath();
        createNewSimulationFile();
        tablePanel = (TablePanel) ideView.getTabPane().getSelectedComponent();
        tablePanel.getModel().removeRow(0);
        ArrayList <Object[]> list = readSimulation(path);
        for(Object obj[]: list){
            tablePanel.getModel().addRow(obj);
        }
        tablePanel.setGlobalComments(globalComments,true);
        globalComments = "";
        
        tablePanel.setNew(false);
        tablePanel.setSaved(true);
        String fileName = file.getName();
        int size = file.getAbsolutePath().length() - fileName.length();
        path = file.getAbsolutePath().substring(0,size);
        tablePanel.setPath( path );
        tablePanel.setFileName(fileName);
        savedFiles.put(tablePanel.getAbsolutePath(), tablePanel);
        int index = ideView.getTabPane().getSelectedIndex();
        ideView.getTabPane().setTitleAt(index,tablePanel.getFileName());      //Change the Tab title
        ideView.getTabPane().setToolTipTextAt(index,tablePanel.getAbsolutePath());//Set the tootlTip
        
    }
    
    private void openAsTextFile(File file){
        try {
            String path = file.getAbsolutePath();
            createNewTextFile();
            file_manager = FileManager.getInstance();
            String text = file_manager.readTextFile(file.getAbsolutePath());
            textPanel.setText(text);
            int index = ideView.getTabPane().getSelectedIndex();
            
            textPanel.setNew(false);
            textPanel.setSaved(true);
            String fileName = file.getName();             //Save fileName
            int size = file.getAbsolutePath().length() - fileName.length();
            path = file.getAbsolutePath().substring(0,size);
            textPanel.setPath( path );
            textPanel.setFileName(fileName);
            savedFiles.put(textPanel.getAbsolutePath(), textPanel); //Add the element with his new key
            ideView.getTabPane().setTitleAt(index,textPanel.getFileName());      //Set the tootlTip
            ideView.getTabPane().setToolTipTextAt(index,textPanel.getAbsolutePath());    //Set the tootlTip
        } catch (FileNotFoundException ex) {
            java.util.logging.Logger.getLogger(IdeMethods.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(IdeMethods.class.getName()).log(Level.SEVERE, null, ex);
        }
               
    }
    

    
    
    
    
    
    public void save(Component com){
        if(com != null && com instanceof TablePanel){
            tablePanel = (TablePanel) com;
            int index = this.ideView.jtPan_Files.indexOfComponent(com);        //Save the index of the ocmponent in the TbaPanel
            String key = this.tablePanel.getAbsolutePath();                      //Save the actual key
            saveSimulation(tablePanel.getModel());
            this.savedFiles.remove( key );                                   //Remove the element from the map
            this.savedFiles.put(tablePanel.getAbsolutePath(), tablePanel);     //Add the element with his new key
            this.ideView.jtPan_Files.setTitleAt(index,tablePanel.getFileName());//Change the Tab title
            this.ideView.jtPan_Files.setToolTipTextAt(index,tablePanel.getAbsolutePath());    //Set the tootlTip
        }else if(com != null && com instanceof TextPanel){
            textPanel = (TextPanel) com;
            int index = this.ideView.jtPan_Files.indexOfComponent(com);        //Save the index of the ocmponent in the TbaPanel
            String key = this.textPanel.getAbsolutePath();                       //Save the actual key
            this.saveText();
            this.savedFiles.remove( key );                                   //Remove the element from the map
            this.savedFiles.put(textPanel.getAbsolutePath(), textPanel);       //Add the element with his new key
            this.ideView.jtPan_Files.setTitleAt(index,textPanel.getFileName()); //Change the Tab title
            this.ideView.jtPan_Files.setToolTipTextAt(index,textPanel.getAbsolutePath());    //Set the tootlTip
        }
    }
    
    public void saveAs(Component com){
        if(com != null && com instanceof TablePanel){
            tablePanel = (TablePanel) com;
            int index = this.ideView.jtPan_Files.indexOfComponent(com);        //Save the index of the component in the TbaPanel
            String key = this.tablePanel.getAbsolutePath();                      //Save the actual key
            tablePanel.setNew(true);
            tablePanel.setSaved(false);
            saveSimulation(tablePanel.getModel());
            this.savedFiles.remove( key );                                   //Remove the element from the map
            this.savedFiles.put(tablePanel.getAbsolutePath(), tablePanel);     //Add the element with his new key
            this.ideView.jtPan_Files.setTitleAt(index,tablePanel.getFileName());//Change the Tab title
            this.ideView.jtPan_Files.setToolTipTextAt(index,tablePanel.getAbsolutePath());    //Set the tootlTip
            tablePanel.setNew(false);
            tablePanel.setSaved(true);
        }else if(com != null && com instanceof TextPanel){
            textPanel = (TextPanel) com;
            int index = this.ideView.jtPan_Files.indexOfComponent(com);        //Save the index of the component in the TbaPanel
            String key = this.textPanel.getAbsolutePath();                       //Save the actual key
            textPanel.setNew(true);
            textPanel.setSaved(false);
            this.saveText();
            this.savedFiles.remove( key );                                   //Remove the element from the map
            this.savedFiles.put(textPanel.getAbsolutePath(), textPanel);       //Add the element with his new key
            this.ideView.jtPan_Files.setTitleAt(index,textPanel.getFileName()); //Change the Tab title
            this.ideView.jtPan_Files.setToolTipTextAt(index,textPanel.getAbsolutePath());    //Set the tootlTip
            textPanel.setNew(false);
            textPanel.setSaved(true);
        }
    }
    
    /**Save changes in all opened files*/
    public void saveAll(){
        int tabs = this.ideView.jtPan_Files.getTabCount();
        while(--tabs >= 0 ){
            save(ideView.jtPan_Files.getComponentAt(tabs));
        }
    }
    
    /** SAVE TEXT FILE*/
    private void saveText(){
        String path;
        String fileName;
        if(textPanel.isNew() && (!textPanel.isSaved() || textPanel.getPath()==null)){                               //if the file is not already saved "Save As"
            File file = messages.saveFileChooser(textPanel.getFileName(), ideView);
            if(file == null){                      //if select Cancel or some error occurs
               return;                                                      //Return (exit form the method)
            }else{
                fileName = file.getName();                                  //Save fileName
                int size = file.getAbsolutePath().length() - fileName.length();
                path = file.getAbsolutePath().substring(0,size);  //Save the absolutePath
            }
        }else if (textPanel.isSaved()){
            messages.showInformationMessage(ideView, Globals.language.getMessage("message.save.noChnahges"), null);
            return;
        }else{                                                             //If the file is already saved... Save "changes"
            path = textPanel.getPath();
            fileName = textPanel.getFileName();
        }
        String fileContent = textPanel.getText();
        this.file_manager =  FileManager.getInstance();
        try {
            this.file_manager.writeTextFile(fileContent, path+fileName);     //Write the file
            this.textPanel.setSaved(true);                          //Mark the file as saved
            this.textPanel.setNew(false);                           //
            this.textPanel.setFileName(fileName);                   //Save the File name in the TablePane
            this.textPanel.setPath(path);                           //Save the path in the TablePane
            this.messages.showInformationMessage( this.ideView,Globals.language.getMessage("message.file.saved") + "\n"+this.textPanel.getAbsolutePath(), null); //Show message
        } catch (IOException ex) {
            logger.error(ex.getMessage());
            this.messages.showErrorMessage( this.ideView,ex.getMessage() , null); //Show error message
        }finally{
            file_manager = null;
        }
    }

    /** SAVE SIMULATION FILE*/
    //Obtain all the content of the Simulation Table and save it
    private void saveSimulation(SimTableModel model) {
        String path;
        String fileName;
        if(tablePanel.isNew() && (!tablePanel.isSaved() || tablePanel.getPath()==null)){                //if the file is not already saved "Save As"
            File file = messages.saveFileChooser(tablePanel.getFileName(),ideView);
            if(file == null){
               return;                                                          //Return (exit form the method)
            }else{
                fileName = file.getName();                                      //Save fileName
                int size = file.getAbsolutePath().length() - fileName.length();
                path = file.getAbsolutePath().substring(0,size);                //Save the absolutePath
                if(!fileName.endsWith(Globals.GIL_EXT)){                  //if the File does not name ends with the SimBlock extention
                    fileName+=Globals.GIL_EXT;                           //add the extention
                }
            }
        }else{                                                                  //If the file is already saved... Save "changes"
            path = this.tablePanel.getPath();
            fileName = this.tablePanel.getFileName();
        }
        String fileContent =
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"   +"\n"
                                                               +"\n"
              + "<!--"                                         +"\n"
              + "Document   : Simulation Table"        +"\n"
              + "Created on : "+Globals.DATETIME_FORMAT.format(new Date())  +"\n"
              + "Author     : "+Globals.APP_NAME+" "+Globals.APP_VERSION+"\n"
              + "-->"                                          +"\n"
                                                               +"\n"
                                                               +"\n"
              +"<simulation file=\""+fileName+"\">"            +"\n"
              +"  <globalcomments>"
                + "<![CDATA["+tablePanel.getGlobalComments()+"]]>"
                + "</globalcomments>"                           +"\n";

        Object obj [];
        int index = 0;
        while(index < model.getRowCount()){
            obj=model.getRow(index);
            fileContent+=
                "  <block id=\""+index+"\">"                        +"\n"
              + "    <active>" +"<![CDATA["+obj[0]+"]]>"+"</active>"+"\n"
              + "    <label>"  +"<![CDATA["+obj[1]+"]]>"+"</label>" +"\n"
              + "    <name>"   +"<![CDATA["+obj[2]+"]]>"+"</name>"  +"\n"
              + "    <values>" +"<![CDATA["+obj[3]+"]]>"+"</values>"+"\n"
              + "    <comment>"+"<![CDATA["+obj[4]+"]]>"+"</comment>"+"\n"
              + "  </block>"                                     +"\n";
             index++;
        }
        fileContent+=
                "</simulation>";
        this.file_manager =  FileManager.getInstance();
        try {
            this.file_manager.writeTextFile(fileContent, path+fileName);     //Write the file
            this.tablePanel.setSaved(true);                          //Mark the file as saved
            this.tablePanel.setNew(false);                           //
            this.tablePanel.setFileName(fileName);                   //Save the File name in the TablePane
            this.tablePanel.setPath(path);                           //Save the path in the TablePane
            this.messages.showInformationMessage(this.ideView, Globals.language.getMessage("message.file.saved") + "\n"+this.tablePanel.getAbsolutePath(), null); //Show message
        } catch (IOException ex) {
            logger.error(ex.getMessage());
            this.messages.showErrorMessage(this.ideView, ex.getMessage() , null); //Show error message
        }finally{
            this.file_manager = null;
        }       
    }
    
    private String getSpaces(String tex, int maxLenght){
        while(tex.length()<maxLenght){
            tex+=" ";
        }
        return tex;
    }

    public void parseGpssToGil(Component selectedComponent) {
        if(selectedComponent instanceof TextPanel){
            textPanel = (TextPanel) selectedComponent;
            sav_int = (GenericFileInterface) selectedComponent;
            if( sav_int.isNew() || sav_int.getPath()==null){
                messages.showInformationMessage(ideView, Globals.language.getMessage("message.sim.before"),null);
            }else if(sav_int.getFileName().endsWith(".gps")){
                ArrayList<Object[]> rows = gpssService.parseGpssToGil(textPanel.getText());
                createNewSimulationFile();
                tablePanel = (TablePanel) ideView.getTabPane().getSelectedComponent();
                tablePanel.getModel().removeRow(0);
                tablePanel.setNew(false);
                tablePanel.setPath(sav_int.getPath());
                String fileName = sav_int.getFileName().substring(0, sav_int.getFileName().indexOf("."))+".gil";
                tablePanel.setFileName(fileName);
                tablePanel.setSaved(false);
                for(Object[] row: rows){
                    tablePanel.getModel().addRow(row);
                }
                save(ideView.getTabPane().getSelectedComponent());   
            }else{
                messages.showInformationMessage(ideView, Globals.language.getMessage("message.not.gpss"),null);
            }
        }
    }
    
    public void saveAsGpsshFile(Component com){
        if(com != null && com instanceof TablePanel){
            tablePanel = (TablePanel) com;
            sav_int = (GenericFileInterface) com;
            if( sav_int.isNew() || sav_int.getPath()==null){
                messages.showInformationMessage(ideView, Globals.language.getMessage("message.sim.before"),null);
            }else{
                try {
                    String fileName = tablePanel.getPath()+(sav_int.getFileName().substring(0, sav_int.getFileName().indexOf("."))+".gps");
                    saveAsGpsshFile(tablePanel.getModel(),tablePanel.getGlobalComments(),fileName);
                    messages.showInformationMessage(ideView, Globals.language.getMessage("message.file.saved") + "\n"+fileName, null);
                    File file = new File(fileName);
                    openAsTextFile(file);
                } catch (Exception ex) {
                    logger.error(ex.getMessage());
                }
            }
        }
    }
    
    public void saveAsGpsshFile(SimTableModel model,String globalComments,String path){
        //File Header
        String fileContent =
                  "* Generated by: "+Globals.APP_NAME+" "+Globals.APP_VERSION+"\n"
                + "* Date: "+ Globals.DATETIME_FORMAT.format( new Date() )+"\n\n";
        
        /*Add comments
        String commentLine[] = globalComments.split("\n");
        int lineIndex=0;
        for(String line:commentLine){
            if(!line.isEmpty()){
                fileContent+="*"+line+"\n";
                if(++lineIndex == commentLine.length){
                   fileContent+="\n\n"; 
                }
            }            
        }*/
        
        //Start reading table
        String row [];
        int index = 0;
        while(index < model.getRowCount()){
            row =model.getStringRow(index);
            
            if( model.isActiveRow(index) ){
                String label = getSpaces(row[1].trim(),7).toUpperCase();
                String block = getSpaces(row[2].trim(),17).toUpperCase();
                String values = row[3].trim().toUpperCase();
                /*String comment = row[4].trim();
                if(!comment.trim().isEmpty()){
                    comment="  //"+comment;
                }*/
                fileContent+= label+block+values+"\n";
            }
            index++;
        }
        this.file_manager =  FileManager.getInstance();
        try {
            this.file_manager.writeTextFile(fileContent, path);     //Write the file
            //this.msg_message.showInformationMessage(this.ide_view, Globals.MSG_FILE_SAVE + "\n"+path, null); //Show message
        } catch (IOException ex) {
            logger.error(ex.getMessage());
            this.messages.showErrorMessage(ideView, ex.getMessage() , null); //Show error message
        }finally{
            this.file_manager = null;
            fileContent = null;
        }     
    }
        
    /** Read the .sbmk file and obtain all rows*/
    private String globalComments;
    private ArrayList <Object[]> readSimulation(String path){
        ArrayList <Object[]> list = null;
        try {
            xml_blocks = new XMLBlocks();
            xml_blocks.read(path);        
            list = xml_blocks.getSimulation();
            globalComments = xml_blocks.getGlobalComments().trim();
            
        } catch (FileNotFoundException ex) {
            java.util.logging.Logger.getLogger(IdeMethods.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(IdeMethods.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SAXException ex) {
            java.util.logging.Logger.getLogger(IdeMethods.class.getName()).log(Level.SEVERE, null, ex);
        }
        return list;
    }

    /*Save a copy of the selected file*/
    public void saveCopy(Component com) {       
        if(com != null && com instanceof TablePanel){
            tablePanel = (TablePanel) com;
            if(!tablePanel.isNew()){
                //Save original values
                String name = this.tablePanel.getFileName();
                boolean status = this.tablePanel.isSaved();
                //Change the path
                this.tablePanel.setFileName(name+Globals.COPY_EXT);
                this.tablePanel.setSaved(false);
                //save
                saveSimulation(tablePanel.getModel());
                //restore values
                this.tablePanel.setSaved(status);
                this.tablePanel.setFileName(name);
            }
        }else if(com != null && com instanceof TextPanel){
            textPanel = (TextPanel) com;
            if(!textPanel.isNew()){
                //Save original values
                String name =    this.textPanel.getFileName();
                boolean status = this.textPanel.isSaved();
                //Change the path
                this.textPanel.setFileName(name+Globals.COPY_EXT);
                this.textPanel.setSaved(false);
                //save
                saveText();
                //restore values
                this.textPanel.setSaved(status);
                this.textPanel.setFileName(name);
            }
        }
    }
    
    
    /** RENAME FILE*/
    public void rename(Component com){
        if(com != null){
            this.sav_int = (GenericFileInterface) com;
            //request a name
            String name = this.messages.showInputMessage( this.ideView,Globals.language.getMessage("message.file.rename"), null,this.sav_int.getFileName());
            if(name != null){
                //check the extention
                if(com instanceof TablePanel && !name.endsWith(Globals.GIL_EXT))
                    name += Globals.GIL_EXT;
                else if(com instanceof TextPanel){
                    //Check if the filealready have an extension
                    String ext=null;
                    if(name.contains("."))
                       ext = name.substring(name.lastIndexOf("."));
                    if(ext==null)
                       name += Globals.TXT_EXT;
                }
                this.savedFiles.remove(sav_int.getAbsolutePath());
                //Obtain index in the Tabbed Pane
                int selected = this.ideView.jtPan_Files.getSelectedIndex();
                this.sav_int.setFileName( name );
                this.ideView.jtPan_Files.setTitleAt(selected, this.sav_int.getFileName());
                this.ideView.jtPan_Files.setToolTipTextAt(selected, this.sav_int.getAbsolutePath());            
                //save
                this.sav_int.setSaved(false);
                this.save(com);
            }
        }
    }

    /**CLOSE FILE
     * Remove the file from Map and Tabbed Panel
     */
    public void close(Component com){
        if(com != null){
            this.sav_int = (GenericFileInterface) com;
            if(!sav_int.isSaved()){
                int option;
                if(this.closinFrame){ //if we are closing the frame, just show  YES-NO option
                    option = this.messages.showQuestionMessage(this.ideView,
                        this.sav_int.getFileName()+": "+Globals.language.getMessage("message.file.closing"), null);
                }else{                //if we are not closing the frame,  show  YES-NO-CANCEL option
                    option = this.messages.showQuestionMessageCancel(this.ideView,
                            this.sav_int.getFileName()+": "+Globals.language.getMessage("message.file.closing"), null);
                }
                if(option == this.messages.YES_OPTION){
                    this.save(com);
                }else if (option == this.messages.CANCEL_OPTION){
                    return;
                }
            }
            //Closing
            this.savedFiles.remove(sav_int.getAbsolutePath());   //Remove from Map
            this.ideView.jtPan_Files.remove(com);                  //Remove from Tab     
            if(com instanceof TablePanel){
                TablePanel table = (TablePanel) com;
                table.getCommentsWindow().setVisible(false);
            }
        }
    }


    /** To close all opened files*/
    public void closeAll(){
        int tabs = this.ideView.jtPan_Files.getTabCount();
        while(--tabs >= 0 )
            this.close(ideView.jtPan_Files.getComponentAt(tabs));
    }

    /**To close all opened file, except the selected one*/
    public void closeOthers(){
        int tabs = this.ideView.jtPan_Files.getTabCount();
        int selected = this.ideView.jtPan_Files.getSelectedIndex();
        while(--tabs >= 0 ){
            if(tabs != selected)
                this.close(ideView.jtPan_Files.getComponentAt(tabs));
        }
    }

        /*******************************************************
         ********************* TABLE MENU **********************
         *******************************************************/    
    public void runSimulation(Component com){
        if(com != null && com instanceof TablePanel){
            tablePanel = (TablePanel) com;
            sav_int = (GenericFileInterface) com;
            if( !sav_int.isNew() && sav_int.isSaved() ){
                if(hasValidLabels(tablePanel.getModel())){
                    String fileName = sav_int.getFileName().substring(0, sav_int.getFileName().indexOf("."));
                    saveAsGpsshFile(tablePanel.getModel(),tablePanel.getGlobalComments(),Globals.GENERIC_GPS);
                    try{
                        exectueGpss(Globals.GENERIC_GPS);
                        String lisContent = FileManager.getInstance().readTextFile(new File(Globals.GENERIC_LIS).getAbsolutePath());
                        openAsNewTextFile(fileName+"_"+Globals.TIME_FORMAT.format(new Date())+".lis",lisContent);
                    } catch (IOException ex) {
                        java.util.logging.Logger.getLogger(IdeMethods.class.getName()).log(Level.SEVERE, null, ex);
                    }catch(GiGenericException ex){
                        messages.showWarningMessage(ideView, ex.getMessage(), null);
                        logger.error(ex.getMessage());
                    }finally{
                        new File(Globals.GENERIC_GPS).delete();
                        new File(Globals.GENERIC_LIS).delete();
                    }
                }else{
                    messages.showInformationMessage(ideView, Globals.language.getMessage("message.label.bigger"), null);
                }
            }else{
                messages.showInformationMessage(ideView, Globals.language.getMessage("message.sim.before"), null);
            }
        }
    }
    
    private boolean hasValidLabels(SimTableModel model){
        String row [];
        int index = 0;
        while(index < model.getRowCount()){
            row =model.getStringRow(index);
            if( model.isActiveRow(index) ){
                String label = row[1].trim();
                if(startsWithLetter(label) && label.length()>=7){
                    return false;
                }
            }
            index++;
        }
        return true;
    }
    
    private boolean startsWithLetter(String label){
        if(label.length()>=1){
            char[] chars = label.toCharArray();
            return Character.isLetter(chars[0]);
        }
        return false;
    }
    
    public void exectueGpss(String file) throws IOException, GiGenericException {
        CmdConnector cmd = new CmdConnector();
        cmd.executeCommand(Globals.CMD_COMMAND+file);
        logger.info(cmd.getInputString());
        logger.info(cmd.getErrorString());    
    }
        
    private GlobalComments cwn_comments;
    public void showComments(Component com) {
        if(com != null && com instanceof TablePanel){
            tablePanel = (TablePanel) com;
            cwn_comments = tablePanel.getCommentsWindow();
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    cwn_comments.setVisible(true);
                }
            });
        }
    }
    

    /** All next methods are solved into TableManel class,
     * but the Ide sends the request here first like the
     * others above.
     * 
     * 1.Obtain the selected component
     * 2.Check that the component is not null
     * 3.Check that the component is a Simulation Table
     * 4.Obtain the Table
     * 5.Execute the method into TablePanel class
     * @param com
     */
    public void insertRowAbove(Component com){
        if(com != null && com instanceof TablePanel){
            try {
                tablePanel = (TablePanel) com;
                tablePanel.addRowAbove();
            } catch (Exception ex) {
                java.util.logging.Logger.getLogger(IdeMethods.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void insertRowBellow(Component com){       
        if(com != null && com instanceof TablePanel){
            try {
                tablePanel = (TablePanel) com;
                tablePanel.addRowBellow();
            } catch (Exception ex) {
                java.util.logging.Logger.getLogger(IdeMethods.class.getName()).log(Level.SEVERE, null, ex);
            }
        }        
    }

    public void insertRowsAbove(Component com){
        if(com != null && com instanceof TablePanel){
            tablePanel = (TablePanel) com;
            tablePanel.addRowsAbove();
        }        
    }

    public void insertRowsBellow(Component com){
        if(com != null && com instanceof TablePanel){
            try {
                tablePanel = (TablePanel) com;
                tablePanel.addRowsBellow();
            } catch (Exception ex) {
                java.util.logging.Logger.getLogger(IdeMethods.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void clearRows(Component com) {
        if(com != null && com instanceof TablePanel){
            try {
                tablePanel = (TablePanel) com;
                tablePanel.clearRows();
            } catch (Exception ex) {
                java.util.logging.Logger.getLogger(IdeMethods.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void deleteRows(Component com) {
        if(com != null && com instanceof TablePanel){
            try {
                tablePanel = (TablePanel) com;
                tablePanel.deleteRow();
            } catch (Exception ex) {
                java.util.logging.Logger.getLogger(IdeMethods.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void active_deactiveRows(Component com) {
        if(com != null && com instanceof TablePanel){
            try {
                tablePanel = (TablePanel) com;
                tablePanel.active_deactiveRows();
            } catch (Exception ex) {
                java.util.logging.Logger.getLogger(IdeMethods.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void activeRows(Component com) {
        if(com != null && com instanceof TablePanel){
            try {
                tablePanel = (TablePanel) com;
                tablePanel.activateRows();
            } catch (Exception ex) {
                java.util.logging.Logger.getLogger(IdeMethods.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void deactiveRows(Component com) {
        if(com != null && com instanceof TablePanel){
            try {
                tablePanel = (TablePanel) com;
                tablePanel.deactivateRows();
            } catch (Exception ex) {
                java.util.logging.Logger.getLogger(IdeMethods.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void goToRow(Component com) {
        if(com != null && com instanceof TablePanel){
            try {
                tablePanel = (TablePanel) com;
                tablePanel.goToRowOrLabel();
            } catch (Exception ex) {
                java.util.logging.Logger.getLogger(IdeMethods.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void moveUp(Component com) {
        if(com != null && com instanceof TablePanel){
            try {
                tablePanel = (TablePanel) com;
                tablePanel.moveUp();
            } catch (Exception ex) {
                java.util.logging.Logger.getLogger(IdeMethods.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void moveDown(Component com) {
        if(com != null && com instanceof TablePanel){
            try {
                tablePanel = (TablePanel) com;
                tablePanel.moveDown();
            } catch (Exception ex) {
                java.util.logging.Logger.getLogger(IdeMethods.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void moveFirst(Component com) {
        if(com != null && com instanceof TablePanel){
            try {
                tablePanel = (TablePanel) com;
                tablePanel.moveFirst();
            } catch (Exception ex) {
                java.util.logging.Logger.getLogger(IdeMethods.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void moveLast(Component com) {
        if(com != null && com instanceof TablePanel){
            try {
                tablePanel = (TablePanel) com;
                tablePanel.moveLast();
            } catch (Exception ex) {
                java.util.logging.Logger.getLogger(IdeMethods.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void copyRows(Component com) {
        if(com != null && com instanceof TablePanel){
                tablePanel = (TablePanel) com;
                tablePanel.copyRows();
        }
    }

    public void cutRows(Component com) {
        if(com != null && com instanceof TablePanel){
            try {
                tablePanel = (TablePanel) com;
                tablePanel.cutRows();
            } catch (Exception ex) {
                java.util.logging.Logger.getLogger(IdeMethods.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }


    public void pasteRows(Component com) {
        if(com != null && com instanceof TablePanel){
                tablePanel = (TablePanel) com;
                tablePanel.pasteRows();
        }
    }

    public void selectAll(Component com) {
        if(com != null && com instanceof TablePanel){
                tablePanel = (TablePanel) com;
                tablePanel.selectAll();
        }
    }

    
    /** Import is an option to obtain all the block from another file
     * an place them into the actual file.
     * 1. Show a OpenDialog
     * 2. if the option is APROVE_OPTION
     *  3. SAve the selected files
     *  4. For each file
     *    5. if the file is a simulation
     *      6. Obtain Blocks
     *      7. Save all blocks in one arraylist
     *    8. Send the array List to the selected table
     *    9. add all block from the array to the table, after selected index
     */
    public void importRows(Component com) throws SAXException, FileNotFoundException, IOException{
        if(com != null && com instanceof TablePanel){
            tablePanel = (TablePanel) com;
            File[] files_open = this.messages.openFileChooser(com);
            //Iterate over each file
            for(File file : files_open){
                String path = file.getAbsolutePath();       //Save the absolutePath
                if(path.endsWith(Globals.GIL_EXT)){  //if the file is a Simulation
                   //Read the file
                   ArrayList<Object[]> list = this.readSimulation(path); //Obtain all rows
                   tablePanel.importRows(list);
                }
            }
            tablePanel.restoreNewRow();
            tablePanel.indexImport = -1;
        }
      
    }

    public void setStatus(int line_counter, int block_counter) {
        this.ideView.jButLineCount.setText(lineStatus+line_counter);
        this.ideView.jButBlockCounter.setText(blockStatus+block_counter);
    }
    
    public void setUndoButtonsEnable(boolean enable){
        this.ideView.jButUndo.setEnabled(enable);
        this.ideView.jItemUndo.setEnabled(enable);
    }
    
    public void setRedoButtonsEnable(boolean enable){
        this.ideView.jButRedo.setEnabled(enable);
        this.ideView.jItemRedo.setEnabled(enable);
    }
    
    public void setCellSelection(Component com,boolean cell) {
        if(com != null && com instanceof TablePanel){
                tablePanel = (TablePanel) com;
                tablePanel.setCellSelection(cell);
        }
    }

    public void undo(Component com){
        if(com != null && com instanceof TablePanel){
            try {
                tablePanel = (TablePanel) com;
                tablePanel.undo(true);
            } catch (Exception ex) {
                java.util.logging.Logger.getLogger(IdeMethods.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
    
    public void redo(Component com) {
        try{    
            if(com != null && com instanceof TablePanel){
                tablePanel = (TablePanel) com;
                tablePanel.undo(false);
            }
        }catch(Exception ex){
        logger.error(ex.getMessage());
        }
    }

}
